{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CE79FBF795C549DCB7FB853079FCAD3B",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "runtime": {
     "execution_status": null,
     "is_visible": false,
     "status": "default"
    },
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "## 使用python的plotly绘制列线图  \n",
    "由于算法是自行推演，不好说完全正确，大家自行判断。  \n",
    "**看点：**  \n",
    "1. Python没有专业绘制列线图的包，一些研究和尝试，大家可以在此基础上进行修改和完善；  \n",
    "2. 对于绘制列线图背后的算法的解析，不一定完全正确，大家自行判断；  \n",
    "3. plotly绘制列线图的方法，比较原始的表现形式，比较容易理解。  \n",
    "\n",
    "\n",
    "![Image Name](https://cdn.kesci.com/upload/rshdhvxinj.png?imageView2/0/w/960/h/960)  \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "644FF44608684EC3A5AB79930ADB4CCA",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "runtime": {
     "execution_status": null,
     "is_visible": false,
     "status": "default"
    },
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "### 1.读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false,
    "id": "1E103679B5BE4C1AB1A0588DC394E231",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "import statsmodels.api as sm\n",
    "import statsmodels.formula.api as smf\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false,
    "id": "9286DC6C68104AB3ABCF0F9C08A80EC6",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3328 entries, 0 to 3327\n",
      "Data columns (total 5 columns):\n",
      " #   Column    Non-Null Count  Dtype   \n",
      "---  ------    --------------  -----   \n",
      " 0   sex       3328 non-null   category\n",
      " 1   ejection  3328 non-null   category\n",
      " 2   age       3328 non-null   int64   \n",
      " 3   bmi       3328 non-null   float64 \n",
      " 4   outcome   3328 non-null   object  \n",
      "dtypes: category(2), float64(1), int64(1), object(1)\n",
      "memory usage: 84.9+ KB\n"
     ]
    }
   ],
   "source": [
    "#读取文件，用户操作\n",
    "data=pd.read_csv('data_dev_factor_cleaned_remove_space.csv')\n",
    "#指定分类变量\n",
    "data['sex']=data['sex'].astype('category')\n",
    "data['ejection']=pd.Categorical(data['ejection'],categories=['Poor','Fair','Good'],ordered=True)\n",
    "data=data.loc[:,['sex','ejection','age','bmi','outcome']]\n",
    "data.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4daad9aa",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": false,
    "id": "3F705825A8B548E286C25E39F3328107",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ejection\n",
       "Good    2130\n",
       "Fair     956\n",
       "Poor     242\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#一个多分类的数据，是列线图中的一类典型的情况\n",
    "data['ejection'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "6e4825dd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3328 entries, 0 to 3327\n",
      "Data columns (total 6 columns):\n",
      " #   Column         Non-Null Count  Dtype  \n",
      "---  ------         --------------  -----  \n",
      " 0   age            3328 non-null   int64  \n",
      " 1   bmi            3328 non-null   float64\n",
      " 2   outcome        3328 non-null   object \n",
      " 3   sex_Male       3328 non-null   int32  \n",
      " 4   ejection_Fair  3328 non-null   int32  \n",
      " 5   ejection_Good  3328 non-null   int32  \n",
      "dtypes: float64(1), int32(3), int64(1), object(1)\n",
      "memory usage: 117.1+ KB\n"
     ]
    }
   ],
   "source": [
    "data_m=pd.get_dummies(data,columns=['sex','ejection'],drop_first=True,dtype=int)\n",
    "data_m.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "a5cbc70c",
   "metadata": {},
   "outputs": [],
   "source": [
    "le=LabelEncoder()\n",
    "data_m['outcome']=le.fit_transform(data_m['outcome'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "1f95bb98",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['age', 'bmi', 'outcome', 'sex_Male', 'ejection_Fair', 'ejection_Good'], dtype='object')"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_m.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0F84945C829F4CBDA451CDC3B712BC9C",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "runtime": {
     "execution_status": null,
     "is_visible": false,
     "status": "default"
    },
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "### 2. 构建线性模型，列线图需要的是模型的参数，beta。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false,
    "id": "18045A36C0E14AC1859ABAEFDBC9590C",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully.\n",
      "         Current function value: 0.238456\n",
      "         Iterations 7\n"
     ]
    }
   ],
   "source": [
    "#构建线性模型，列线图需要的是模型的参数。\n",
    "#再此之前需要进行incode \n",
    "model_logit=smf.logit('outcome~ age +bmi+sex_Male+ejection_Good+ejection_Fair',data_m).fit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": false,
    "id": "BD91D78D9D024FE7AE4AB2AAB4C80441",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Intercept       -2.661101\n",
       "age              0.032976\n",
       "bmi             -0.039664\n",
       "sex_Male        -0.193388\n",
       "ejection_Good   -1.297959\n",
       "ejection_Fair   -0.936878\n",
       "dtype: float64"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model_logit_params=model_logit.params\n",
    "model_logit_params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "30815839",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.66110094,  0.03297645, -0.03966392, -0.19338821, -1.29795908,\n",
       "       -0.93687808])"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model_logit_params.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "307b928a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Intercept', 'age', 'bmi', 'sex_Male', 'ejection_Good', 'ejection_Fair']"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model_logit_params.index.to_list()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2AEB1436A2AA4789A43E703A1FD0F171",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "runtime": {
     "execution_status": null,
     "is_visible": false,
     "status": "default"
    },
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "### 3.构建绘制列线图所需要的数据  \n",
    "- 绘制线条的数据可能和标签数据并不是同一组数据，只是两者之间有对应关系，这在列线图中是常见的一个操作；  \n",
    "- 连续变量，二分类和多分类具有不同的处理方式；  \n",
    "- 下一步可能是需要这部分更加自动化一些。设计：包可能包括2～3函数，一个函数计算所需要的数据，另一个函数进行绘图，如果再有就增加一些标记之类的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": false,
    "id": "FCE26B27FB454D0DA65EEAB1073BADB8",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": true,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3328 entries, 0 to 3327\n",
      "Data columns (total 8 columns):\n",
      " #   Column         Non-Null Count  Dtype  \n",
      "---  ------         --------------  -----  \n",
      " 0   age            3328 non-null   float64\n",
      " 1   bmi            3328 non-null   float64\n",
      " 2   sex_Male       3328 non-null   float64\n",
      " 3   ejection_Good  3328 non-null   float64\n",
      " 4   ejection_Fair  3328 non-null   float64\n",
      " 5   Intercept      3328 non-null   float64\n",
      " 6   total          3328 non-null   float64\n",
      " 7   probability    3328 non-null   float64\n",
      "dtypes: float64(8)\n",
      "memory usage: 208.1 KB\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "cols=model_logit_params.index.to_list()\n",
    "params=model_logit_params.values\n",
    "#原始数据，用于做数字标签\n",
    "meta_df=data_m.loc[:,cols[1:]]\n",
    "meta_df['Intercept']=np.repeat(1,meta_df.shape[0])\n",
    "\n",
    "#meta数据1，beta与X的乘积,现在没有连续变量和分类变量的区别\n",
    "for col, beta in zip(cols,params):\n",
    "    meta_df[col]= [x* beta for x in meta_df[col]]\n",
    "\n",
    "#合计数据，用于计算预测概率\n",
    "meta_df['total']=meta_df.sum(axis=1)\n",
    "meta_df['probability']=[1/(1+np.exp(-z)) for z in meta_df['total']]\n",
    "meta_df.info()\n",
    "#之前纠结的一个问题是列线图不考虑intercept？现在倾向于认为最终计算概率的时候是考虑的，但是计算总分的时候没有考虑。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "ce9a8232",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3328 entries, 0 to 3327\n",
      "Data columns (total 8 columns):\n",
      " #   Column         Non-Null Count  Dtype  \n",
      "---  ------         --------------  -----  \n",
      " 0   age            3328 non-null   float64\n",
      " 1   bmi            3328 non-null   float64\n",
      " 2   sex_Male       3328 non-null   float64\n",
      " 3   ejection_Good  3328 non-null   float64\n",
      " 4   ejection_Fair  3328 non-null   float64\n",
      " 5   Intercept      3328 non-null   float64\n",
      " 6   total          3328 non-null   float64\n",
      " 7   probability    3328 non-null   float64\n",
      "dtypes: float64(8)\n",
      "memory usage: 208.1 KB\n"
     ]
    }
   ],
   "source": [
    "meta_df.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false,
    "id": "7E968BA719AA47EC9592CFB96793319C",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Intercept:0.0\n",
      "age:2.4402575909399884\n",
      "bmi:1.8714487519021634\n",
      "sex_Male:0.19338821024701608\n",
      "ejection_Good:1.2979590821153464\n",
      "ejection_Fair:0.9368780777646967\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2.4402575909399884"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将数据转化成绘制列线图需要的数据，上面一部分是后台计算所需要的数据\n",
    "#求最大数据,即每个变量最大值和最小值之间distances中最大的一个， 这个最大的distance会处理为100， 其它的distance根据比例绘制\n",
    "ls_max_distance=[]\n",
    "for col in cols:\n",
    "    one_distance=np.max(meta_df[col].values)-np.min(meta_df[col].values)\n",
    "    print(col+':'+f\"{one_distance}\")\n",
    "    ls_max_distance.append(one_distance)\n",
    "    \n",
    "max_distance=np.max(ls_max_distance)\n",
    "\n",
    "max_distance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "f37b97de",
   "metadata": {},
   "outputs": [],
   "source": [
    "score_df=meta_df.copy()[cols]\n",
    "for col in cols:\n",
    "    score_df[col]=(meta_df[col]-meta_df[col].min())*100/max_distance\n",
    "score_df['total']=score_df.sum(axis=1)\n",
    "score_df['probability']=meta_df['probability']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "cf0b5154",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Intercept</th>\n",
       "      <th>age</th>\n",
       "      <th>bmi</th>\n",
       "      <th>sex_Male</th>\n",
       "      <th>ejection_Good</th>\n",
       "      <th>ejection_Fair</th>\n",
       "      <th>total</th>\n",
       "      <th>probability</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.0</td>\n",
       "      <td>63.513514</td>\n",
       "      <td>34.002194</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>38.392589</td>\n",
       "      <td>135.908297</td>\n",
       "      <td>0.038372</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.0</td>\n",
       "      <td>71.621622</td>\n",
       "      <td>30.813236</td>\n",
       "      <td>7.92491</td>\n",
       "      <td>53.189429</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>163.549196</td>\n",
       "      <td>0.072642</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.0</td>\n",
       "      <td>78.378378</td>\n",
       "      <td>52.511606</td>\n",
       "      <td>7.92491</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>38.392589</td>\n",
       "      <td>177.207484</td>\n",
       "      <td>0.098545</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>79.729730</td>\n",
       "      <td>47.019067</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>38.392589</td>\n",
       "      <td>165.141386</td>\n",
       "      <td>0.075303</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.0</td>\n",
       "      <td>72.972973</td>\n",
       "      <td>38.902235</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>38.392589</td>\n",
       "      <td>150.267797</td>\n",
       "      <td>0.053611</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Intercept        age        bmi  sex_Male  ejection_Good  ejection_Fair  \\\n",
       "0        0.0  63.513514  34.002194   0.00000       0.000000      38.392589   \n",
       "1        0.0  71.621622  30.813236   7.92491      53.189429       0.000000   \n",
       "2        0.0  78.378378  52.511606   7.92491       0.000000      38.392589   \n",
       "3        0.0  79.729730  47.019067   0.00000       0.000000      38.392589   \n",
       "4        0.0  72.972973  38.902235   0.00000       0.000000      38.392589   \n",
       "\n",
       "        total  probability  \n",
       "0  135.908297     0.038372  \n",
       "1  163.549196     0.072642  \n",
       "2  177.207484     0.098545  \n",
       "3  165.141386     0.075303  \n",
       "4  150.267797     0.053611  "
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "score_df.head()# score + original data is visualization data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "bb35fd42",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100.0"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "score_df['age'].max()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "id": "a3db374c",
   "metadata": {},
   "outputs": [],
   "source": [
    "score_df_plus=score_df.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "79718558",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 3328 entries, 0 to 3327\n",
      "Data columns (total 7 columns):\n",
      " #   Column       Non-Null Count  Dtype  \n",
      "---  ------       --------------  -----  \n",
      " 0   Intercept    3328 non-null   float64\n",
      " 1   age          3328 non-null   float64\n",
      " 2   bmi          3328 non-null   float64\n",
      " 3   sex_Male     3328 non-null   float64\n",
      " 4   total        3328 non-null   float64\n",
      " 5   probability  3328 non-null   float64\n",
      " 6   ejection     3328 non-null   float64\n",
      "dtypes: float64(7)\n",
      "memory usage: 182.1 KB\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Intercept</th>\n",
       "      <th>age</th>\n",
       "      <th>bmi</th>\n",
       "      <th>sex_Male</th>\n",
       "      <th>total</th>\n",
       "      <th>probability</th>\n",
       "      <th>ejection</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.0</td>\n",
       "      <td>63.513514</td>\n",
       "      <td>34.002194</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>135.908297</td>\n",
       "      <td>0.038372</td>\n",
       "      <td>38.392589</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.0</td>\n",
       "      <td>71.621622</td>\n",
       "      <td>30.813236</td>\n",
       "      <td>7.92491</td>\n",
       "      <td>163.549196</td>\n",
       "      <td>0.072642</td>\n",
       "      <td>53.189429</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.0</td>\n",
       "      <td>78.378378</td>\n",
       "      <td>52.511606</td>\n",
       "      <td>7.92491</td>\n",
       "      <td>177.207484</td>\n",
       "      <td>0.098545</td>\n",
       "      <td>38.392589</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>79.729730</td>\n",
       "      <td>47.019067</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>165.141386</td>\n",
       "      <td>0.075303</td>\n",
       "      <td>38.392589</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.0</td>\n",
       "      <td>72.972973</td>\n",
       "      <td>38.902235</td>\n",
       "      <td>0.00000</td>\n",
       "      <td>150.267797</td>\n",
       "      <td>0.053611</td>\n",
       "      <td>38.392589</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Intercept        age        bmi  sex_Male       total  probability  \\\n",
       "0        0.0  63.513514  34.002194   0.00000  135.908297     0.038372   \n",
       "1        0.0  71.621622  30.813236   7.92491  163.549196     0.072642   \n",
       "2        0.0  78.378378  52.511606   7.92491  177.207484     0.098545   \n",
       "3        0.0  79.729730  47.019067   0.00000  165.141386     0.075303   \n",
       "4        0.0  72.972973  38.902235   0.00000  150.267797     0.053611   \n",
       "\n",
       "    ejection  \n",
       "0  38.392589  \n",
       "1  53.189429  \n",
       "2  38.392589  \n",
       "3  38.392589  \n",
       "4  38.392589  "
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "plus_cols=['ejection_Good','ejection_Fair']\n",
    "value_name='ejection'\n",
    "score_df_plus[value_name]=score_df_plus[plus_cols].sum(axis=1)\n",
    "#将df['ejcection']中最大值替换为0\n",
    "score_df_plus[value_name]=[0 if x==score_df_plus[value_name].max() else x for x in score_df_plus[value_name]]\n",
    "score_df_plus=score_df_plus.drop(plus_cols,axis=1)\n",
    "score_df_plus.info()\n",
    "score_df_plus.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "id": "E77B860B20DF474E8183459B7AB9D2DC",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [],
   "source": [
    "#连续变量获得step\n",
    "#获取原始值的distance，使用score的distance除以实际值的distance,获得刻度线的宽度（step），保证最大和最小值都在线条上，分类变量不需要\n",
    "#用于绘制刻度间隔step，也就是单位变量（比如age）所代表的分数,即每一岁代表的分数\n",
    "step_age=score_df_plus['age'].max()/(data_m['age'].max()-data_m['age'].min())\n",
    "step_bmi=score_df_plus['bmi'].max()/(data_m['bmi'].max()-data_m['bmi'].min())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "id": "AC831FE174C1417C82F6B18991632585",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.        , 38.39258942, 53.18942914])"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#分类变量不需要step，需要的是几个点\n",
    "np.unique(score_df_plus['ejection'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "id": "16a2afa0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ejection\n",
       "38.392589    2130\n",
       "53.189429     956\n",
       "0.000000      242\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 134,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "score_df_plus['ejection'].value_counts()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "id": "df774da2",
   "metadata": {},
   "outputs": [],
   "source": [
    "score_df_plus.to_csv('score_df_plus.csv')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "79E747E966E64584A8A487B479E45900",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "runtime": {
     "execution_status": null,
     "is_visible": false,
     "status": "default"
    },
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "### 4.绘制列线图\n",
    "绘图需要两个数据集，1. 原始数据集，这里是data_m,包含数据的原始值，作为标签；2. 评分数据集，这里是score_df,包含计算的得分。\n",
    "\n",
    "\n",
    "还有第三个数据集，中间数据集meta_df,是系数与变量值的乘积，是计算score_df的中间值，但是包含预测概率，max_distance(是一个常数，要从数据集中获得)，每个变量的meta_df最小值要保留。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "id": "1283432E78524CC888123652D8300921",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [],
   "source": [
    "import plotly.graph_objects as go"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "collapsed": false,
    "id": "62FE8F71F65C41D8B3DFF7742A8035D8",
    "jupyter": {},
    "notebookId": "6424d87ec030c2ab0bab6f4f",
    "scrolled": true,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": [],
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[177.83094751 211.03659832 238.0834983  254.81663423]\n"
     ]
    },
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "marker": {
          "color": "blue",
          "size": 15,
          "symbol": "142"
         },
         "mode": "lines+markers",
         "type": "scatter",
         "x": [
          0,
          5,
          10,
          15,
          20,
          25,
          30,
          35,
          40,
          45,
          50,
          55,
          60,
          65,
          70,
          75,
          80,
          85,
          90,
          95,
          100
         ],
         "xaxis": "x2",
         "y": [
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3
         ],
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": "blue",
          "symbol": "142"
         },
         "mode": "lines+markers",
         "type": "scatter",
         "x": [
          0,
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18,
          19,
          20,
          21,
          22,
          23,
          24,
          25,
          26,
          27,
          28,
          29,
          30,
          31,
          32,
          33,
          34,
          35,
          36,
          37,
          38,
          39,
          40,
          41,
          42,
          43,
          44,
          45,
          46,
          47,
          48,
          49,
          50,
          51,
          52,
          53,
          54,
          55,
          56,
          57,
          58,
          59,
          60,
          61,
          62,
          63,
          64,
          65,
          66,
          67,
          68,
          69,
          70,
          71,
          72,
          73,
          74,
          75,
          76,
          77,
          78,
          79,
          80,
          81,
          82,
          83,
          84,
          85,
          86,
          87,
          88,
          89,
          90,
          91,
          92,
          93,
          94,
          95,
          96,
          97,
          98,
          99,
          100
         ],
         "xaxis": "x2",
         "y": [
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3
         ],
         "yaxis": "y2"
        },
        {
         "mode": "text",
         "text": [
          0,
          5,
          10,
          15,
          20,
          25,
          30,
          35,
          40,
          45,
          50,
          55,
          60,
          65,
          70,
          75,
          80,
          85,
          90,
          95,
          100
         ],
         "type": "scatter",
         "x": [
          0,
          5,
          10,
          15,
          20,
          25,
          30,
          35,
          40,
          45,
          50,
          55,
          60,
          65,
          70,
          75,
          80,
          85,
          90,
          95,
          100
         ],
         "xaxis": "x2",
         "y": [
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5
         ],
         "yaxis": "y2"
        },
        {
         "mode": "text",
         "text": "Points",
         "type": "scatter",
         "x": [
          -3
         ],
         "xaxis": "x",
         "y": [
          3
         ],
         "yaxis": "y"
        },
        {
         "marker": {
          "color": "red",
          "symbol": "142"
         },
         "mode": "lines+markers",
         "type": "scatter",
         "x": [
          0,
          2.7027027027027026,
          5.405405405405405,
          8.108108108108109,
          10.81081081081081,
          13.513513513513512,
          16.216216216216218,
          18.91891891891892,
          21.62162162162162,
          24.324324324324323,
          27.027027027027025,
          29.72972972972973,
          32.432432432432435,
          35.13513513513514,
          37.83783783783784,
          40.54054054054054,
          43.24324324324324,
          45.945945945945944,
          48.648648648648646,
          51.35135135135135,
          54.05405405405405,
          56.75675675675676,
          59.45945945945946,
          62.16216216216216,
          64.86486486486487,
          67.56756756756756,
          70.27027027027027,
          72.97297297297297,
          75.67567567567568,
          78.37837837837837,
          81.08108108108108,
          83.78378378378378,
          86.48648648648648,
          89.1891891891892,
          91.89189189189189,
          94.5945945945946,
          97.29729729729729,
          100
         ],
         "xaxis": "x4",
         "y": [
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3
         ],
         "yaxis": "y4"
        },
        {
         "mode": "text",
         "text": [
          "90",
          "88",
          "86",
          "84",
          "82",
          "80",
          "78",
          "76",
          "74",
          "72",
          "70",
          "68",
          "66",
          "64",
          "62",
          "60",
          "58",
          "56",
          "54",
          "52",
          "50",
          "48",
          "46",
          "44",
          "42",
          "40",
          "38",
          "36",
          "34",
          "32",
          "30",
          "28",
          "26",
          "24",
          "22",
          "20",
          "18",
          "16"
         ],
         "type": "scatter",
         "x": [
          0,
          2.7027027027027026,
          5.405405405405405,
          8.108108108108109,
          10.81081081081081,
          13.513513513513512,
          16.216216216216218,
          18.91891891891892,
          21.62162162162162,
          24.324324324324323,
          27.027027027027025,
          29.72972972972973,
          32.432432432432435,
          35.13513513513514,
          37.83783783783784,
          40.54054054054054,
          43.24324324324324,
          45.945945945945944,
          48.648648648648646,
          51.35135135135135,
          54.05405405405405,
          56.75675675675676,
          59.45945945945946,
          62.16216216216216,
          64.86486486486487,
          67.56756756756756,
          70.27027027027027,
          72.97297297297297,
          75.67567567567568,
          78.37837837837837,
          81.08108108108108,
          83.78378378378378,
          86.48648648648648,
          89.1891891891892,
          91.89189189189189,
          94.5945945945946,
          97.29729729729729,
          100
         ],
         "xaxis": "x4",
         "y": [
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5
         ],
         "yaxis": "y4"
        },
        {
         "mode": "text",
         "text": "Age",
         "type": "scatter",
         "x": [
          -3
         ],
         "xaxis": "x3",
         "y": [
          3
         ],
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "red",
          "symbol": "142"
         },
         "mode": "lines+markers",
         "type": "scatter",
         "x": [
          0,
          38.39258942347192,
          53.18942913790392
         ],
         "xaxis": "x4",
         "y": [
          1,
          1,
          1
         ],
         "yaxis": "y4"
        },
        {
         "mode": "text",
         "text": [
          "poor",
          "fair",
          "good"
         ],
         "type": "scatter",
         "x": [
          0,
          38.39258942347192,
          53.18942913790392
         ],
         "xaxis": "x4",
         "y": [
          1.5,
          1.5,
          1.5
         ],
         "yaxis": "y4"
        },
        {
         "mode": "text",
         "text": "Ejection",
         "type": "scatter",
         "x": [
          -3
         ],
         "xaxis": "x3",
         "y": [
          1
         ],
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "red",
          "symbol": "142"
         },
         "mode": "lines+markers",
         "type": "scatter",
         "x": [
          0,
          7.924909688428542
         ],
         "xaxis": "x4",
         "y": [
          -1,
          -1
         ],
         "yaxis": "y4"
        },
        {
         "mode": "text",
         "text": [
          "femal",
          "male"
         ],
         "type": "scatter",
         "x": [
          0,
          7.924909688428542
         ],
         "xaxis": "x4",
         "y": [
          -0.5,
          -0.5
         ],
         "yaxis": "y4"
        },
        {
         "mode": "text",
         "text": "Sex",
         "type": "scatter",
         "x": [
          -3
         ],
         "xaxis": "x3",
         "y": [
          -1
         ],
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "green",
          "size": 15,
          "symbol": "142"
         },
         "mode": "lines+markers",
         "type": "scatter",
         "x": [
          24.570506529439257,
          44.57050652943926,
          64.57050652943926,
          84.57050652943926,
          104.57050652943926,
          124.57050652943926,
          144.57050652943926,
          164.57050652943926,
          184.57050652943926,
          204.57050652943926,
          224.57050652943926,
          244.57050652943926,
          264.5705065294393,
          284.5705065294393,
          304.5705065294393
         ],
         "xaxis": "x6",
         "y": [
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3,
          3
         ],
         "yaxis": "y6"
        },
        {
         "mode": "text",
         "text": [
          25,
          45,
          65,
          85,
          105,
          125,
          145,
          165,
          185,
          205,
          225,
          245,
          265,
          285,
          305
         ],
         "type": "scatter",
         "x": [
          24.570506529439257,
          44.57050652943926,
          64.57050652943926,
          84.57050652943926,
          104.57050652943926,
          124.57050652943926,
          144.57050652943926,
          164.57050652943926,
          184.57050652943926,
          204.57050652943926,
          224.57050652943926,
          244.57050652943926,
          264.5705065294393,
          284.5705065294393,
          304.5705065294393
         ],
         "xaxis": "x6",
         "y": [
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5,
          3.5
         ],
         "yaxis": "y6"
        },
        {
         "mode": "text",
         "text": "Total",
         "type": "scatter",
         "x": [
          -3
         ],
         "xaxis": "x5",
         "y": [
          3
         ],
         "yaxis": "y5"
        },
        {
         "marker": {
          "color": "green",
          "symbol": "142"
         },
         "mode": "lines+markers",
         "type": "scatter",
         "x": [
          177.83094750904138,
          211.03659832360682,
          238.08349830162138,
          254.81663423473339
         ],
         "xaxis": "x6",
         "y": [
          1,
          1,
          1,
          1
         ],
         "yaxis": "y6"
        },
        {
         "mode": "text",
         "text": [
          0.1,
          0.2,
          0.33,
          0.42
         ],
         "type": "scatter",
         "x": [
          177.83094750904138,
          211.03659832360682,
          238.08349830162138,
          254.81663423473339
         ],
         "xaxis": "x6",
         "y": [
          1.5,
          1.5,
          1.5,
          1.5
         ],
         "yaxis": "y6"
        },
        {
         "mode": "text",
         "text": "prob",
         "type": "scatter",
         "x": [
          -3
         ],
         "xaxis": "x5",
         "y": [
          1
         ],
         "yaxis": "y5"
        }
       ],
       "layout": {
        "height": 600,
        "paper_bgcolor": "#ffffff",
        "plot_bgcolor": "#ffffff",
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "heatmapgl": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmapgl"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "width": 1000,
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          0.099
         ],
         "visible": false
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0.109,
          1
         ],
         "range": [
          -5,
          105
         ],
         "visible": false
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0,
          0.099
         ],
         "visible": false
        },
        "xaxis4": {
         "anchor": "y4",
         "domain": [
          0.109,
          1
         ],
         "range": [
          -5,
          105
         ],
         "visible": false
        },
        "xaxis5": {
         "anchor": "y5",
         "domain": [
          0,
          0.099
         ],
         "visible": false
        },
        "xaxis6": {
         "anchor": "y6",
         "domain": [
          0.109,
          1
         ],
         "range": [
          -5,
          354.8166342347334
         ],
         "visible": false
        },
        "yaxis": {
         "anchor": "x",
         "autorange": false,
         "domain": [
          0.8775000000000001,
          1
         ],
         "range": [
          2,
          4
         ],
         "visible": false
        },
        "yaxis2": {
         "anchor": "x2",
         "autorange": false,
         "domain": [
          0.8775000000000001,
          1
         ],
         "range": [
          2,
          4
         ],
         "visible": false
        },
        "yaxis3": {
         "anchor": "x3",
         "autorange": false,
         "domain": [
          0.255,
          0.8675
         ],
         "range": [
          -2,
          4
         ],
         "visible": false
        },
        "yaxis4": {
         "anchor": "x4",
         "autorange": false,
         "domain": [
          0.255,
          0.8675
         ],
         "range": [
          -2,
          4
         ],
         "visible": false
        },
        "yaxis5": {
         "anchor": "x5",
         "autorange": false,
         "domain": [
          0,
          0.245
         ],
         "range": [
          0,
          4
         ],
         "visible": false
        },
        "yaxis6": {
         "anchor": "x6",
         "autorange": false,
         "domain": [
          0,
          0.245
         ],
         "range": [
          0,
          4
         ],
         "visible": false
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#fig整体布局，三行两列，\n",
    "# title='Explaination of Linear Model'\n",
    "fig = go.Figure().set_subplots(rows=3,cols=2,vertical_spacing=0.01,\n",
    "    horizontal_spacing=0.01,column_widths=[0.1,0.9],\n",
    "    row_heights=[0.1,0.5,0.2])#\n",
    "fig.update_yaxes(\n",
    "    autorange=False,\n",
    "    visible=False\n",
    "    )#禁止自动调整刻度，通用\n",
    "fig.update_xaxes(visible=False)#禁止自动调整刻度，通用\n",
    "fig.update_yaxes(row=2,range=[-2,4])\n",
    "fig.update_yaxes(row=3,range=[0,4])\n",
    "fig.update_yaxes(row=1,range=[2,4])\n",
    "fig.update_xaxes(row=1,col=2,range=[-5,105])\n",
    "fig.update_xaxes(row=2,col=2,range=[-5,105])\n",
    "fig.update_xaxes(row=3,col=2,range=[-5,max(score_df_plus['total'])+100])\n",
    "\n",
    "fig.update_layout(width=1000,height=600,showlegend=False,paper_bgcolor=\"#ffffff\",plot_bgcolor=\"#ffffff\")\n",
    "#---------------------------------------绘制100标尺--------------------------------------------------#\n",
    "#python arrange的规则是“前包后不包”，所以要多一位数\n",
    "fig.add_trace(go.Scatter(mode='lines+markers',y=np.repeat(3,105/5),\n",
    "                         x=np.arange(0,105,5),\n",
    "                         marker={'symbol':'142',\"color\":'blue','size':15},  \n",
    "              ), row=1,col=2)\n",
    "\n",
    "#绘制次要刻度\n",
    "fig.add_trace(go.Scatter(mode='lines+markers',\n",
    "                         x=np.arange(0,101),\n",
    "                         y=np.repeat(3,101),#离开x轴的位置\n",
    "                         marker={'symbol':'142','color':'blue'},\n",
    "                         ),row=1,col=2)\n",
    "#绘制数据数字标签，原始数据\n",
    "fig.add_trace(go.Scatter(mode='text',\n",
    "                         x=np.arange(0,105,5),\n",
    "                         y=np.repeat(3.5,105/5),\n",
    "                         text=np.arange(0,105,5),\n",
    "                        ),row=1,col=2)\n",
    "#绘制左侧label,col=1\n",
    "fig.add_trace(go.Scatter(mode='text',x=[-3],y=[3],text='Points'),row=1,col=1)\n",
    "\n",
    "#------------------------------------------绘制age---------------------------------------------#\n",
    "\n",
    "x_age_range = np.arange(0, max(score_df_plus['age']) + 2*step_age, 2*step_age)\n",
    "\n",
    "# 主刻度\n",
    "fig.add_trace(go.Scatter(\n",
    "    mode='lines+markers',\n",
    "    y=np.repeat(3, len(x_age_range)),\n",
    "    x=x_age_range,\n",
    "    marker={'symbol': '142', \"color\": 'red'}\n",
    "), row=2, col=2)\n",
    "\n",
    "# 绘制数据数字标签，原始数据\n",
    "fig.add_trace(go.Scatter(\n",
    "    mode='text',\n",
    "    x=x_age_range,\n",
    "    y=np.repeat(3.5, len(x_age_range)),\n",
    "    text=[int(x) for x in np.arange(np.floor(min(data_m['age'])),np.floor(max(data_m['age'])+2),2)][::-1],#1step_age 对应1 岁\n",
    "), row=2, col=2)\n",
    "\n",
    "# 绘制左侧label，col=1\n",
    "fig.add_trace(go.Scatter(\n",
    "    mode='text',\n",
    "    x=[-3],\n",
    "    y=[3],\n",
    "    text='Age'\n",
    "), row=2, col=1)\n",
    "\n",
    "#----------------------------绘制ejection_std------------------------#\n",
    "x_ejection_range=np.unique(score_df_plus['ejection'])\n",
    "fig.add_trace(go.Scatter(mode='lines+markers',y=np.repeat(1,len(x_ejection_range)),\n",
    "                         x=x_ejection_range,\n",
    "                         marker={'symbol':'142',\"color\":'red'},  \n",
    "              ), row=2,col=2)\n",
    "\n",
    "#绘制数据数字标签，这应该是原始数据才对\n",
    "fig.add_trace(go.Scatter(mode='text',\n",
    "                         x=x_ejection_range,#标尺数据\n",
    "                         y=np.repeat(1.5,len(x_ejection_range)),\n",
    "                         text=['poor','fair','good'],#原始数据\n",
    "                        ),row=2,col=2)\n",
    "#绘制左侧label,col=1\n",
    "fig.add_trace(go.Scatter(mode='text',x=[-3],y=[1],text='Ejection'),row=2,col=1)\n",
    "\n",
    "# #-----------------------------------sex--------------------------------------#\n",
    "x_sex_range=np.unique(score_df_plus['sex_Male'])\n",
    "fig.add_trace(go.Scatter(mode='lines+markers',y=np.repeat(-1,len(x_sex_range)),\n",
    "                         x=x_sex_range,\n",
    "                         marker={'symbol':'142',\"color\":'red'},  \n",
    "              ), row=2,col=2)\n",
    "\n",
    "#绘制数据数字标签，这应该是原始数据才对\n",
    "fig.add_trace(go.Scatter(mode='text',\n",
    "                         x=x_sex_range,\n",
    "                         y=np.repeat(-0.5,len(x_sex_range)),\n",
    "                         text=['femal','male']\n",
    "                        ),row=2,col=2)\n",
    "#绘制左侧label,col=1\n",
    "fig.add_trace(go.Scatter(mode='text',x=[-3],y=[-1],text='Sex'),row=2,col=1)\n",
    "\n",
    "# #----------------------------------total score------------------------------------------#\n",
    "#总分与各个变量得分没有对应关系，是和概率之间有对应关系，所以可以是独立的坐标系\n",
    "x_total_range=np.arange(score_df_plus['total'].min()-50,max(score_df_plus['total'])+50,20)\n",
    "fig.add_trace(go.Scatter(mode='lines+markers',y=np.repeat(3,len(x_total_range)),\n",
    "                         x=x_total_range,#\n",
    "                         marker={'symbol':'142',\"color\":'green','size':15},  \n",
    "              ), row=3,col=2)\n",
    "\n",
    "\n",
    "#绘制数据数字标签，这应该是原始数据才对\n",
    "fig.add_trace(go.Scatter(mode='text',\n",
    "                         x=x_total_range,#标尺数据\n",
    "                         y=np.repeat(3.5,len(x_total_range)),#s\n",
    "                         text=x_total_range.round(0)#原始数据\n",
    "                        ),row=3,col=2)\n",
    "#绘制左侧label,col=1\n",
    "fig.add_trace(go.Scatter(mode='text',x=[-3],y=[3],text='Total'),row=3,col=1)\n",
    "\n",
    "\n",
    "# #----------------------------------------prob-用total划线而标记probality----------------------------------------#\n",
    "#给定一个概率的列表\n",
    "prob_range=[0,0.1,0.2,0.4,0.5,0.6,0.8,0.85,0.9]\n",
    "\n",
    "x_proba_range=[]#取toal_betaX_std的值\n",
    "proba_text_label=[]\n",
    "for x in prob_range:\n",
    "    #＜于0.1的，且距离0.1最近的值\n",
    "    proba_closest=max(score_df_plus[score_df_plus['probability']<=x]['probability'],default=None)\n",
    "    if proba_closest is not None: \n",
    "        label=round(proba_closest,2)\n",
    "        value=score_df_plus[score_df_plus['probability']==proba_closest]['total']\n",
    "        x_proba_range.append(value)\n",
    "        proba_text_label.append(label)\n",
    "    \n",
    "x_proba_range=np.unique(x_proba_range)\n",
    "print(x_proba_range)\n",
    "proba_text_label=np.unique(proba_text_label)\n",
    "fig.add_trace(go.Scatter(mode='lines+markers',y=np.repeat(1,len(x_proba_range)),\n",
    "                         x=x_proba_range,\n",
    "                         marker={'symbol':'142',\"color\":'green'},  \n",
    "              ), row=3,col=2)\n",
    "\n",
    "#绘制数据数字标签，这应该是原始数据才对\n",
    "fig.add_trace(go.Scatter(mode='text',\n",
    "                         x=x_proba_range,#标尺数据\n",
    "                         y=np.repeat(1.5,len(x_proba_range)),\n",
    "                         text=proba_text_label#原始数据\n",
    "                        ),row=3,col=2)\n",
    "#绘制左侧label,col=1\n",
    "fig.add_trace(go.Scatter(mode='text',x=[-3],y=[1],text='prob'),row=3,col=1)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "sar_gui",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
